
#include <atomic>
#include <glog/logging.h>

int main(int argc, char* argv[])
{
    google::SetStderrLogging(google::LogSeverity(FLAGS_minloglevel));
    google::InitGoogleLogging(argv[0]);

    // LOG(INFO) << "x.is_lock_free: " << x.is_lock_free();
    // LOG(INFO) << "x.is_always_lock_free: " << x.is_always_lock_free;
    // LOG(INFO) << "ATOMIC_BOOL_LOCK_FREE: " << ATOMIC_BOOL_LOCK_FREE;
    // LOG(INFO) << "ATOMIC_CHAR_LOCK_FREE: " << ATOMIC_CHAR_LOCK_FREE;
    // // std::atomic<bool> x;
    // // atomic_bool y;

    // std::atomic_flag f = ATOMIC_FLAG_INIT;
    // f.clear(std::memory_order_release);
    // bool x = f.test_and_set(std::memory_order_acq_rel);
    // LOG(INFO) << "X: " << x;

    // std::atomic<bool> b;
    // LOG(INFO) << "b init: " << b.load(std::memory_order_acquire);
    // LOG(INFO) << "b exch: " << b.exchange(false) << ":" << b.load();
    // b.store(true, std::memory_order_release);
    // LOG(INFO) << "b exch: " << b.exchange(false) << ":" << b.load();
    // LOG(INFO) << "b exch: " << b.exchange(true) << ":" << b.load();
    
    // bool expected = true;
    // std::atomic<bool> b(true); // 在其他地方设置，可能被多个线程修改
    // while (true) {
    //     auto res = b.compare_exchange_weak(expected, false);
    //     LOG(INFO) << "res: " << res << ", expected: " << expected;
    //     if (res && expected) {
    //         break;
    //     }
    // }
    // LOG(INFO) << "b: " << b.load(std::memory_order_acquire) << ", b exch: " << b.exchange(true) << " : " << b.load();

    struct MyClass {
        int val;
        bool flag;
        // explicit MyClass(int val_ = 0, bool flag_ = 0)
        //     : val(val_)
        //     , flag(flag_)
        // {
        // }
        bool operator==(MyClass const& other) const { return val == other.val; }
    };
    std::atomic<MyClass> my_atomic_class(MyClass(0, 0));

    MyClass expected { 0, 1 };
    if (my_atomic_class.load() == expected) {
        LOG(INFO) << "atomic value == expected";
    }
    if (my_atomic_class.compare_exchange_strong(expected, MyClass(1, 1))) {
        LOG(INFO) << "exchange success!";
    }
    auto res = my_atomic_class.load();
    LOG(INFO) << res.val << " : " << res.flag;
    return 0;
}